using Azure.Domain.Models;
using Azure.Domain.Services;
using Azure.Infrastructure;
using Rhino.Mocks;
using Xunit;

namespace Azure.Tests.Domain
{
    public class BlogConfigurationFacts : Facts<BlogConfiguration>
    {
        public IRepository<SiteConfiguration> Repository
        {
            get { return Mock<IRepository<SiteConfiguration>>();  }
        }

        [Fact]
        public void ConfigurationIsLoadedWhenPropertyIsAccessed()
        {
            var actual = new SiteConfiguration { Title = "Test"};
            Repository.Stub(x => x.Load(actual.PartitionKey, actual.RowKey)).Return(actual);

            var config = ClassUnderTest.Configuration;

            Assert.NotNull(config);
            Assert.Equal("Test", config.Title);
        }

        [Fact]
        public void ConfigurationReturnsNullConfigurationWhenTHereIsNoConfigurationInRepository()
        {
            var config = ClassUnderTest.Configuration;

            Assert.NotNull(config);
            Assert.IsType(typeof (BlogConfiguration.NullSiteConfiguration), config);
        }

        [Fact]
        public void ConfigurationPropertyIsCachedAfterFirstAccess()
        {
            var actual = new SiteConfiguration { Title = "Test" };
            Repository.Expect(x => x.Load(actual.PartitionKey, actual.RowKey)).Return(actual).Repeat.Once();

            var config1 = ClassUnderTest.Configuration;
            var config2 = ClassUnderTest.Configuration;

            Repository.VerifyAllExpectations();
        }

        [Fact]
        public void SavePersistsTheConfigurationInTheRepositoryUsingInsertWhenThereIsNoConfiguration()
        {
            var config = new SiteConfiguration
                             {
                                 Email = "you@you.com", 
                                 Title = "Test Site"
                             };
            ClassUnderTest.Save(config);
            Repository.AssertWasCalled(x => x.Insert(Arg<SiteConfiguration>.Is.Anything));
        }

        [Fact]
        public void SavePersistsTheConfigurationInTheRepositoryUsingUpdateWhenThereIsAConfiguration()
        {
            var config = new SiteConfiguration
            {
                Email = "you@you.com",
                Title = "Test Site"
            };
            Repository.Stub(x => x.Load(config.PartitionKey, config.RowKey)).Return(config);
            ClassUnderTest.Save(config);
            Repository.AssertWasCalled(x => x.Update(Arg<SiteConfiguration>.Is.Anything));
        }
    }
}